package com.x.component.connectivity;


import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
//import com.android.settingslib.Utils;
//import com.android.settingslib.mobile.MobileStatusTracker.MobileStatus;
//import com.android.settingslib.mobile.TelephonyIcons;
import java.lang.IllegalArgumentException;
import java.util.Arrays;
import java.util.List;

import com.x.component.connectivity.MobileStatusTracker.MobileStatus;

/**
 * Box for all policy-related state used in MobileSignalController
 */
public class MobileState extends ConnectivityState {

    public String networkName;
    public String networkNameData;
    public boolean dataSim;
    public boolean dataConnected;
    public boolean isEmergency;
    public boolean airplaneMode;
    public boolean carrierNetworkChangeMode;
    public boolean isDefault;
    public boolean userSetup;
    public boolean roaming;
    public int dataState;
    public boolean defaultDataOff;
    public boolean imsRegistered;
    public boolean voiceCapable;
    public boolean videoCapable;
    public boolean mobileDataEnabled;
    public boolean roamingDataEnabled;
    public int imsRegistrationTech;

    public TelephonyDisplayInfo telephonyDisplayInfo = new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_UNKNOWN,
            TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE);
    public ServiceState serviceState;
    public SignalStrength signalStrength;

    public MobileState() {
        super();
    }

    public boolean isDataConnected() {
        return connected && dataState == TelephonyManager.DATA_CONNECTED;
    }

    public int getVoiceServiceState() {
        return serviceState != null ? serviceState.getState() : -1;
    }

    public boolean isNoCalling() {
        return serviceState != null && serviceState.getState() != ServiceState.STATE_IN_SERVICE;
    }

    public String getOperatorAlphaShort() {
        return serviceState != null ? serviceState.getOperatorAlphaShort() : "";
    }

    public boolean isCdma() {
        return signalStrength != null && !signalStrength.isGsm();
    }

    public boolean isEmergencyOnly() {
        return serviceState != null && serviceState.isEmergencyOnly();
    }

    public boolean isInService() {
        return Utils.isInService(serviceState);
    }

    public boolean isRoaming() {
        return serviceState != null && serviceState.getRoaming();
    }

    public int getVoiceNetworkType() {
        return serviceState != null ? serviceState.getVoiceNetworkType() : TelephonyManager.NETWORK_TYPE_UNKNOWN;
    }

    public int getDataNetworkType() {
        return serviceState != null ? serviceState.getDataNetworkType() : TelephonyManager.NETWORK_TYPE_UNKNOWN;
    }

    public void setFromMobileStatus(MobileStatus mobileStatus) {
        activityIn = mobileStatus.activityIn;
        activityOut = mobileStatus.activityOut;
        dataSim = mobileStatus.dataSim;
        carrierNetworkChangeMode = mobileStatus.carrierNetworkChangeMode;
        dataState = mobileStatus.dataState;
        signalStrength = mobileStatus.signalStrength;
        telephonyDisplayInfo = mobileStatus.telephonyDisplayInfo;
        serviceState = mobileStatus.serviceState;
    }

    @Override
    public void toString(StringBuilder builder) {
        super.toString(builder);
        builder.append(',');
        builder.append("dataSim=").append(dataSim).append(",");
        builder.append("networkName=").append(networkName).append(",");
        builder.append("networkNameData=").append(networkNameData).append(",");
        builder.append("dataConnected=").append(dataConnected).append(",");
        builder.append("roaming=").append(roaming).append(",");
        builder.append("isDefault=").append(isDefault).append(",");
        builder.append("isEmergency=").append(isEmergency).append(",");
        builder.append("airplaneMode=").append(airplaneMode).append(",");
        builder.append("carrierNetworkChangeMode=").append(carrierNetworkChangeMode).append(",");
        builder.append("userSetup=").append(userSetup).append(",");
        builder.append("dataState=").append(dataState).append(",");
        builder.append("defaultDataOff=").append(defaultDataOff).append(",");
        builder.append("imsRegistered=").append(imsRegistered).append(",");
        builder.append("imsRegistrationTech=").append(imsRegistrationTech).append(",");
        builder.append("voiceCapable=").append(voiceCapable).append(",");
        builder.append("videoCapable=").append(videoCapable).append(",");
        builder.append("mobileDataEnabled=").append(mobileDataEnabled).append(",");
        builder.append("roamingDataEnabled=").append(roamingDataEnabled).append(",");

        // Computed properties
        builder.append("showQuickSettingsRatIcon=").append(showQuickSettingsRatIcon()).append(",");
        builder.append("voiceServiceState=").append(getVoiceServiceState()).append(",");
        builder.append("isInService=").append(isInService()).append(",");

//        builder.append("serviceState=").append(serviceState != null ? serviceState.minLog() : "(null)").append(",");
//        builder.append("signalStrength=").append(signalStrength != null ? signalStrength.minLog() : "(null)").append(",");
        builder.append("displayInfo=").append(telephonyDisplayInfo);
    }

    @Override
    public List<String> tableColumns() {
        List<String> columns = Arrays.asList("dataSim", "networkName", "networkNameData", "dataConnected", "roaming",
                "isDefault", "isEmergency", "airplaneMode", "carrierNetworkChangeMode", "userSetup", "dataState",
                "defaultDataOff", "showQuickSettingsRatIcon", "voiceServiceState", "isInService", "serviceState",
                "signalStrength", "displayInfo");

        List<String> superColumns = super.tableColumns();
        superColumns.addAll(columns);
        return superColumns;
    }

    @Override
    public List<String> tableData() {
        List<String> data = Arrays.asList(String.valueOf(dataSim), networkName, networkNameData,
                String.valueOf(dataConnected), String.valueOf(roaming), String.valueOf(isDefault),
                String.valueOf(isEmergency), String.valueOf(airplaneMode), String.valueOf(carrierNetworkChangeMode),
                String.valueOf(userSetup), String.valueOf(dataState), String.valueOf(defaultDataOff),
                String.valueOf(showQuickSettingsRatIcon()), String.valueOf(getVoiceServiceState()),
//                String.valueOf(isInService()), serviceState != null ? serviceState.minLog() : "(null)",
				/* signalStrength != null ? signalStrength.minLog() : "(null)", */ String.valueOf(telephonyDisplayInfo));

        List<String> superData = super.tableData();
        superData.addAll(data);
        return superData;
    }

    @Override
    public boolean equals(Object other) {
        if (this == other)
            return true;
        if (other == null || getClass() != other.getClass())
            return false;
        if (!super.equals(other))
            return false;

        MobileState that = (MobileState) other;

        if (dataSim != that.dataSim)
            return false;
        if (dataConnected != that.dataConnected)
            return false;
        if (isEmergency != that.isEmergency)
            return false;
        if (airplaneMode != that.airplaneMode)
            return false;
        if (carrierNetworkChangeMode != that.carrierNetworkChangeMode)
            return false;
        if (isDefault != that.isDefault)
            return false;
        if (userSetup != that.userSetup)
            return false;
        if (roaming != that.roaming)
            return false;
        if (dataState != that.dataState)
            return false;
        if (defaultDataOff != that.defaultDataOff)
            return false;
        if (imsRegistered != that.imsRegistered)
            return false;
        if (imsRegistrationTech != that.imsRegistrationTech)
            return false;
        if (voiceCapable != that.voiceCapable)
            return false;
        if (videoCapable != that.videoCapable)
            return false;
        if (mobileDataEnabled != that.mobileDataEnabled)
            return false;
        if (roamingDataEnabled != that.roamingDataEnabled)
            return false;
        if (!telephonyDisplayInfo.equals(that.telephonyDisplayInfo))
            return false;
        if (serviceState != null ? !serviceState.equals(that.serviceState) : that.serviceState != null)
            return false;
        return signalStrength != null ? signalStrength.equals(that.signalStrength) : that.signalStrength == null;
    }

    @Override
    public int hashCode() {
        int result = super.hashCode();
        result = 31 * result + (networkName != null ? networkName.hashCode() : 0);
        result = 31 * result + (networkNameData != null ? networkNameData.hashCode() : 0);
        result = 31 * result + (dataSim ? 1 : 0);
        result = 31 * result + (dataConnected ? 1 : 0);
        result = 31 * result + (isEmergency ? 1 : 0);
        result = 31 * result + (airplaneMode ? 1 : 0);
        result = 31 * result + (carrierNetworkChangeMode ? 1 : 0);
        result = 31 * result + (isDefault ? 1 : 0);
        result = 31 * result + (userSetup ? 1 : 0);
        result = 31 * result + (roaming ? 1 : 0);
        result = 31 * result + dataState;
        result = 31 * result + (defaultDataOff ? 1 : 0);
        result = 31 * result + (imsRegistered ? 1 : 0);
        result = 31 * result + imsRegistrationTech;
        result = 31 * result + (voiceCapable ? 1 : 0);
        result = 31 * result + (videoCapable ? 1 : 0);
        result = 31 * result + (mobileDataEnabled ? 1 : 0);
        result = 31 * result + (roamingDataEnabled ? 1 : 0);
        result = 31 * result + telephonyDisplayInfo.hashCode();
        result = 31 * result + (serviceState != null ? serviceState.hashCode() : 0);
        result = 31 * result + (signalStrength != null ? signalStrength.hashCode() : 0);
        return result;
    }

    /** toString() is a little more verbose than we need. Just log the fields we read */
    private String minLog(ServiceState serviceState) {
        return "serviceState={" +
                "state=" + serviceState.getState() +
                ", isEmergencyOnly=" + serviceState.isEmergencyOnly() +
                ", roaming=" + serviceState.getRoaming() +
                ", operatorNameAlphaShort=" + serviceState.getOperatorAlphaShort() +
                "}";
    }

    /** toString() is a little more verbose than we need. Just log the fields we read */
    private String minLog(SignalStrength signalStrength) {
        return "signalStrength={" +
                "isGsm=" + signalStrength.isGsm() +
                ", level=" + signalStrength.getLevel() +
                "}";
    }

    /** toString() is a little more verbose than we need. Just log the fields we read */
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        toString(builder);
        return builder.toString();
    }

    /** toString() is a little more verbose than we need. Just log the fields we read */
    public String minLog() {
        return "MobileState{" +
                "networkName='" + networkName + '\'' +
                ", networkNameData='" + networkNameData + '\'' +
                ", dataSim=" + dataSim +
                ", dataConnected=" + dataConnected +
                ", isEmergency=" + isEmergency +
                ", airplaneMode=" + airplaneMode +
                ", carrierNetworkChangeMode=" + carrierNetworkChangeMode +
                ", isDefault=" + isDefault +
                ", userSetup=" + userSetup +
                ", roaming=" + roaming +
                ", dataState=" + dataState +
                ", defaultDataOff=" + defaultDataOff +
                ", imsRegistered=" + imsRegistered +
                ", imsRegistrationTech=" + imsRegistrationTech +
                ", voiceCapable=" + voiceCapable +
                ", videoCapable=" + videoCapable +
                ", mobileDataEnabled=" + mobileDataEnabled +
                ", roamingDataEnabled=" + roamingDataEnabled +
                ", telephonyDisplayInfo=" + telephonyDisplayInfo +
                ", serviceState=" + (serviceState != null ? minLog(serviceState) : "(null)") +
                ", signalStrength=" + (signalStrength != null ? minLog(signalStrength) : "(null)") +
                '}';
    }

    /** toString() is a little more verbose than we need. Just log the fields we read */
    public String log() {
        return "MobileState{" +
                "networkName='" + networkName + '\'' +
                ", networkNameData='" + networkNameData + '\'' +
                ", dataSim=" + dataSim +
                ", dataConnected=" + dataConnected +
                ", isEmergency=" + isEmergency +
                ", airplaneMode=" + airplaneMode +
                ", carrierNetworkChangeMode=" + carrierNetworkChangeMode +
                ", isDefault=" + isDefault +
                ", userSetup=" + userSetup +
                ", roaming=" + roaming +
                ", dataState=" + dataState +
                ", defaultDataOff=" + defaultDataOff +
                ", imsRegistered=" + imsRegistered +
                ", imsRegistrationTech=" + imsRegistrationTech +
                ", voiceCapable=" + voiceCapable +
                ", videoCapable=" + videoCapable +
                ", mobileDataEnabled=" + mobileDataEnabled +
                ", roamingDataEnabled=" + roamingDataEnabled +
                ", telephonyDisplayInfo=" + telephonyDisplayInfo +
                ", serviceState=" + (serviceState != null ? serviceState.toString() : "(null)") +
                ", signalStrength=" + (signalStrength != null ? signalStrength.toString() : "(null)") +
                '}';
    }

    public boolean hasActivityIn() {
        return dataConnected && !carrierNetworkChangeMode && activityIn;
    }

    public boolean hasActivityOut() {
        return dataConnected && !carrierNetworkChangeMode && activityOut;
    }

    public boolean showQuickSettingsRatIcon() {
        return dataConnected || isDataDisabledOrNotDefault();
    }

    public boolean isDataDisabledOrNotDefault() {
//        return iconGroup == TelephonyIcons.DATA_DISABLED || iconGroup == TelephonyIcons.NOT_DEFAULT_DATA && userSetup;
        return true;
    }

    @Override
    public void copyFrom(ConnectivityState other) {
        if (!(other instanceof MobileState)) {
            throw new IllegalArgumentException("MobileState can only update from another MobileState");
        }

        MobileState o = (MobileState) other;
        super.copyFrom(o);

        networkName = o.networkName;
        networkNameData = o.networkNameData;
        dataSim = o.dataSim;
        dataConnected = o.dataConnected;
        isEmergency = o.isEmergency;
        airplaneMode = o.airplaneMode;
        carrierNetworkChangeMode = o.carrierNetworkChangeMode;
        isDefault = o.isDefault;
        userSetup = o.userSetup;
        roaming = o.roaming;
        dataState = o.dataState;
        defaultDataOff = o.defaultDataOff;
        imsRegistered = o.imsRegistered;
        imsRegistrationTech = o.imsRegistrationTech;
        voiceCapable = o.voiceCapable;
        videoCapable = o.videoCapable;
        mobileDataEnabled = o.mobileDataEnabled;
        roamingDataEnabled = o.roamingDataEnabled;

        telephonyDisplayInfo = o.telephonyDisplayInfo;
        serviceState = o.serviceState;
        signalStrength = o.signalStrength;
    }
}
